<!--
@description    添加/编辑漏斗 侧边弹窗
@author         秦俊强
@email          458112865@qq.com
@create         2021-06-05
-->

<template>
  <div class="content" ref="boxHeight">
    <div class="entryFunnel">
      <div class="nameFunnel">
        <p class="name">漏斗名称</p>
        <el-input v-model="funnelName" size="small"></el-input>
      </div>

      <div class="windowFunnel">
        <p class="window">漏斗窗口期</p>
        <el-tooltip class="item" effect="dark" content="用户触发第一个步骤后，在指定窗口期内完成整个漏斗，即算作完成了整个转化。" placement="bottom">
          <i class="el-icon-info"></i>
        </el-tooltip>
        <el-select v-model="funnelWindowsTime" placeholder="请选择" size="small" value-key="value">
          <el-option style="color: #333" v-for="item in funnelWindowsTimeList" :key="item.value" :label="item.label" :value="item"> </el-option>
        </el-select>
        <div v-if="funnelWindowsTime.label === '自定义'">
          <el-input size="small" style="width: 100px;margin-left: 10px" v-model="customTime" @keyup.native="positiveIntegerCheck"></el-input>
          <el-select v-model="customTimeType" size="small" style="width: 100px;margin-left: 10px">
            <el-option style="color: #333" v-for="item in timeUnit" :key="item.label" :label="item.label" :value="item.label"> </el-option>
          </el-select>
        </div>
      </div>
    </div>

    <div class="stepsFunne">
      <div class="titleTop">
        <p class="title">漏斗步骤</p>
        <div class="titleRight">
          <el-switch v-model="show" inactive-text="设置关联属性" inactive-color="#ccc"> </el-switch>
          <el-tooltip class="item" effect="dark" content="至少选择2两个属性，且所选类型必须一致。" placement="bottom">
            <i class="el-icon-question"></i>
          </el-tooltip>
        </div>
      </div>
      <div class="steps" v-for="(mes, index) in funnelItem" :key="mes.key">
        <div class="step-wrap">
          <!--        序号+1-->
          <div class="one">{{ index + 1 }}</div>
          <!--        选择框-->
          <div class="app click1">
            <div @click="cho(mes)">
              <span :title="mes.mes.cname">{{ mes.mes.cname || '请选择' }}</span>
              <i class="el-icon-arrow-down"></i>
            </div>
            <!--          内置选择框-->
            <options v-if="mes.act" @cho="choList" :origin="mes"></options>
            <div class="filterBox"></div>
          </div>

          <!--          <el-button type="text" icon="el-icon-plus" size="small" @click="editCond(index)">自定义筛选条件</el-button>-->

          <div style="margin-left: 10px">
            <i v-show="funnelItem.length > 2" class="el-icon-delete" title="移除筛选项" @click="remvnoCond(index)"></i>
            <el-button type="text" icon="el-icon-plus" size="small" @click="editCond(index)">自定义筛选条件</el-button>
          </div>

        </div>

        <CustomScreen :ref="`customScreenRef${index}`" :isSupName="true"
                      :supName="funnelItem[index].mes.name"
                      :editArr="funnelItem[index].mes.filter"></CustomScreen>

        <div class="content" v-if="show">
          <p>关联属性</p>
          <el-select v-model="funnelItem[index].mes.relevanceField" placeholder="请选择" size="small">
            <el-option v-for="item in funnelItem[index].mes.attList" :key="item.cname" :label="item.cname" :value="item.name"> </el-option>
          </el-select>
        </div>
      </div>

      <div class="button">
        <el-button type="success" @click="add">
          <i class="el-icon-plus"></i>
          增加步骤
        </el-button>
      </div>
      <div class="bottom">
        <el-button class="cancel" @click="cancel">取消</el-button>
        <el-button type="success" class="keep" @click="save">保存漏斗 </el-button>
      </div>
    </div>
  </div>
</template>

<script>
/* dataType 类型配置 */
import DataTypeConfig from './dataType.config.js'
import ElementUI from 'element-ui'
import options from './options'
/* 自定义筛选条件 */
import CustomScreen from './customScreen'
import { changeList, funnelCreate, getFunnelDetail } from './api.config'
import { propertyList } from './api.config'
import { thinglList } from './api.config'
export default {
  name: 'edit-funnel',

  props: {
    d: {
      type: Object,
      default: null
    }
  },
  components: {
    options,
    CustomScreen
  },

  data() {
    return {
      access:true,
      /* 二级事件列表 */
      thinglList: [],

      /* 漏斗窗口期 */
      funnelWindowsTime: {},

      /* 自定义漏斗时间 */
      customTime: '',

      /* 自定义漏斗时间类型--用户选择值 */
      customTimeType: '',

      /* 默认漏斗时间类型 */
      timeUnit: DataTypeConfig.defaultTimeUnit,

      /* 默认漏斗可选取时间总类 */
      funnelWindowsTimeList: DataTypeConfig.defaultFunnelWindowsTimeList,

      /* 漏洞名称 */
      funnelName: '',

      /* 漏斗id 修改时传入 */
      funnelId: '',

      /* 展示关联属性开关 */
      show: false,

      /* 漏斗步骤数组 */
      funnelItem: [
        { key: '1', act: false, mes: { relevanceField: '' , attList: [] } },
        { key: '2', act: false, mes: { relevanceField: '' , attList: [] } }
      ],


    }
  },

  created() {
    this.getThinglList()
  },
  methods: {
    /* 初始化数据 */
    initializeData() {
      this.funnelItem = [
        { key: '1', act: false, mes: { relevanceField: '' , attList: [],cname:'' } },
        { key: '2', act: false, mes: { relevanceField: '' , attList: [],cname:'' } }
      ]
      this.funnelId = ''
      this.funnelName = ''
      this.funnelWindowsTime = {}
      this.show = false
    },

    //正整数校验
    positiveIntegerCheck() {
      this.customTime = this.customTime.replace(/[^.\d]/g,'');
      this.customTime = this.customTime.replace('.','');
      if (this.customTime.length >= 2 && this.customTime.charAt(0) === '0') {
        this.customTime = 0;
      }
    },

    /**
     * 接收编辑时数据
     * @param analysisOptsValue 当前编辑时点击对象参数
     */
    receiveDate(analysisOptsValue) {
      let t = this

      //漏斗id
      this.funnelId = analysisOptsValue.id

      //漏斗名称
      this.funnelName = analysisOptsValue.name

      //将漏斗窗期赋值为空
      this.funnelWindowsTime = {}

      //窗期时间
      let windowTime = analysisOptsValue.maxConvertTime

      //获取漏斗窗期对象
      for (let i = 0; i < this.funnelWindowsTimeList.length; i++) {
        if (windowTime === Number(this.funnelWindowsTimeList[i].value)) {
          this.funnelWindowsTime = this.funnelWindowsTimeList[i]
        }
      }

      //如果没有匹配的数据 证明为自定义数据 计算类型与对应类型时间
      if (this.funnelWindowsTime.value == null) {
        this.funnelWindowsTime = { label: '自定义', value: '自定义' }
        if (windowTime % 1440 === 0) {
          this.customTime = windowTime / 1440
          this.customTimeType = '天'
        } else if (analysisOptsValue.maxConvertTime % 60 === 0) {
          this.customTime = windowTime / 60
          this.customTimeType = '小时'
        } else {
          this.customTime = windowTime
          this.customTimeType = '分钟'
        }
      }

      /* 查询漏斗 获取漏斗详情 */
      getFunnelDetail({ id: this.funnelId }).then((res) => {
        // 返回状态码如果不是 200，说明数据异常，需弹窗提示
        if (res.data.code !== 200) {
          this.$alert(res.data.msg, '提示', { type: 'warning'});
          return;
        }

        // 存储漏斗步骤
        let funnelItem = [];

        let data = res.data.data;
        let steps = data.steps;

        this.show = data.relevanceField;  // 关联属性

        //  获取步骤进行遍历
        for (let i = 0; i < steps.length; i++) {
          // "event_name": "$AppClick",
          let eventName = steps[i].eventName;

          // 遍历数组获得event_name的展示昵称
          let eventCname = '';
          for (let j = 0; j < this.thinglList.length; j++) {
            let thingItem = this.thinglList[j];
            if (eventName === thingItem.name) {
              eventCname = thingItem.cname;
              break;
            }
          }

          // 遍历关联属性 如果存在就开启关联属性展示 并把关联属性插入到此item下
          let relevanceField = '';
          if (this.show && steps[i].relevanceField) {
            let arr = steps[i].relevanceField.split('.');
            relevanceField = arr[arr.length - 1];
          }

          //创建漏斗数组的一个item 赋值然后插入进数组
          let funnelItemValues = {
            name: '',
            key: i + 1,
            act: false,
            mes: {
              name: res.data.data.steps[i].eventName,
              cname: eventCname,
              relevanceField: relevanceField,
              filter: res.data.data.steps[i].filter
            }
          };


          funnelItem.push(funnelItemValues)
        }
        t.funnelItem = funnelItem;
        let that = this;
        for (let i = 0; i < t.funnelItem.length; i++) {
            // 获取每个事件的关联属性
            // 使用此数组替换当前漏斗数组
            propertyList({
              events: t.funnelItem[i].mes.name,
              type: 'event',
              needEventTime:true
            }).then((res) => {
              t.funnelItem[i].mes.attList=res.data.data.rows
              t.funnelItem[i].mes.attList.unshift({ cname: '无', name: '' })
              that.$forceUpdate()
            })
        }
      })

    },

    /* 获取事件列表 */
    getThinglList() {
      thinglList({
      }).then((res) => {
        // 返回状态码如果不是 200，说明数据异常，需弹窗提示
        if (res.data.code !== 200) {
          this.$alert(res.data.msg, '提示', { type: 'warning'});
          return;
        }

        this.thinglList = res.data.data.rows;
      })
    },

    /* 选择漏斗步骤时回调 */
    choList(mes) {
      this.funnelItem.map((item) => {
        if (item.key == mes.origin.key) {
          item.mes = mes.mes;
          this.attri(item.key,mes.mes.name)
          item.act = false;
        }
      })
    },

    /* 当前步骤列表 */
    getStepItems: function(haveNull) {
      // eslint-disable-line no-unused-vars
      let stepItem = []

      let funnelItem = this.funnelItem

      //组装漏斗步骤
      for (let i = 0; i < funnelItem.length; i++) {
        let relevanceField = "";
        this.$refs['customScreenRef' + i][0].getFilterConditions();
        if (funnelItem[i].mes.relevanceField !== undefined){
          relevanceField = 'event.' + funnelItem[i].mes.name + '.' + funnelItem[i].mes.relevanceField;
        }

        let customScreenRef = this.$refs['customScreenRef' + i][0].getFilterConditions()
        console.log("customScreenRef"+customScreenRef)
        console.log(customScreenRef)
        for (let j = 0; j < customScreenRef.length; j++) {
          if (customScreenRef[j].params.length === 0) {
            haveNull=[{isNull:true}]
            break;
          }
        }
        stepItem.push({
          eventName: funnelItem[i].mes.name,
          eventCName: funnelItem[i].mes.cname,
          customName: '',
          //关联对象
          relevanceField: relevanceField,
          //当前步骤下的限制条件
          filter: this.$refs['customScreenRef' + i][0].getFilterConditions()
        })
      }
      console.log(haveNull)
      //窗口期特殊情况时间计算 单位:分钟
      if (this.funnelWindowsTime.label === '自定义') {
        //判断是否为数字
        let isNumber = this.isNumber(this.customTime)
        if (isNumber === false) {
          //Message 消息提示
          ElementUI.Message({
            message: '您输入的自定义窗口期数据只能是数字',
            type: 'error'
          })
          //返回错误信息
          return 'error'
        }

        let time = this.customTime
        if (this.customTimeType === '分钟') {
          time = Number(time)
        }
        if (this.customTimeType === '小时') {
          time = Number(time) * 60
        }
        if (this.customTimeType === '天') {
          time = Number(time) * 1440
        }

        //窗口期小于等于0或者大于10年直接返回
        if (this.customTime <= 0 || this.customTime > 5256000) {
          //Message 消息提示
          ElementUI.Message({
            message: '自定义窗口期时间范围，1分钟到10年',
            type: 'error'
          })
          //返回错误信息
          return 'error'
        }

        this.funnelWindowsTime.value = time
      }

      return stepItem
    },

    /* 保存漏斗 */
    save() {
      // 获取漏斗步骤
      this.access = true;
      let haveNull =[]// eslint-disable-line no-unused-vars
      let stepItem = this.getStepItems(haveNull);
      if (haveNull[0]?.isNull === false) {
          this.$message({
            message: "输入值不能为空",
            type: 'warn'
          });
          return;
      }
      if (stepItem === 'error' || !this.access) { return; }

      let apiMap = {
        create: {
          api: funnelCreate,        // 创建接口
          successMsg: '创建成功',   // 成功提示
        },

        edit: {
          api: changeList,          // 编辑接口
          successMsg: '编辑成功',   // 成功提示
        }
      };

      // 通用参数
      let param = {
        appId: this.$store.state.global.appItem.appId,
        relevanceField: this.show,                      // 关联属性开关

        name: this.funnelName,
        maxConvertTime: this.funnelWindowsTime.value,
        steps: stepItem,
      };

      let k = 'create';   // 默认 创建接口

      // 如果有 funnelId，说明当前操作是编辑漏斗
      if (this.funnelId) {
        param['id'] = this.funnelId;
        k = 'edit';
      }

      apiMap[k].api(param).then((res) => {
        // 返回状态码如果不是 200，说明数据异常，需弹窗提示
        if (res.data.code !== 200) {
          this.$alert(res.data.msg, '提示', { type: 'warning'});
          return;
        }

        // 通知父级更新数据
        this.$emit('getFunnelsEvent');

        // 关闭右侧边弹窗面板
        this.$emit('showeditbool', false);

        // 成功提示
        this.$message({
          message: apiMap[k].successMsg,
          type: 'success'
        });
      })
          .catch((error) => {
        console.log(error);
      });

    },

    cancel() {
      this.funnelName = ''
      this.funnelWindowsTime = {}
      this.funnelId = ''
      this.funnelItem = [
        { key: '1', act: false, mes: { relevanceField: '' , attList: [] } },
        { key: '2', act: false, mes: { relevanceField: '' , attList: [] } }
      ]
      this.$emit('close')

    },

    //工具方法 判断是否为数字 返回true为数字
    isNumber(val) {
      var regPos = /^\d+(\.\d+)?$/ //非负浮点数
      var regNeg = /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/ //负浮点数
      if (regPos.test(val) || regNeg.test(val)) {
        return true
      } else {
        return false
      }
    },

    cho(mes) {
      if (mes.act == false) {
        this.funnelItem.map((item) => {
          //全部赋值为false
          item.act = false
        })
        mes.act = true
      } else {
        this.funnelItem.map((item) => {
          item.act = false
        })
      }
    },
    add() {
      this.funnelItem.push({
        relevanceField: '',
        key: this.funnelItem.length + 1,
        act: false,
        mes: {}
      })
    },
    attri(index,event) {
      let that =this
      propertyList({
        events: event,
        type: 'event',
        needEventTime:true
      }).then((res) => {
        // 返回状态码如果不是 200，说明数据异常，需弹窗提示
        if (res.data.code !== 200) {
          this.$alert(res.data.msg, '提示', { type: 'warning'});
          return;
        }

        for (let i = 0; i <that.funnelItem.length ; i++) {
          if (that.funnelItem[i].key === index){
            that.funnelItem[index-1].mes.attList = res.data.data.rows
            that.funnelItem[index-1].mes.attList.unshift({ cname: '无', name: '' })
            that.$forceUpdate()
          }
        }
      })
    },
    change() {
      changeList({ id: '' }).then((res) => {
        console.log(res);

        // 返回状态码如果不是 200，说明数据异常，需弹窗提示
        if (res.data.code !== 200) {
          this.$alert(res.data.msg, '提示', { type: 'warning'});
          return;
        }
      })
    },
    remvnoCond(i) {
      // 移除筛选条件
      if (typeof i === 'number') {
        // eslint-disable-next-line no-empty
        i = i - 1 //点击第三个元素 实际上是list的list[2]
        for (let j = i + 1; j <= this.funnelItem.length - 1; j++) {
          this.funnelItem[j].key = this.funnelItem[j].key - 1
        }
        this.funnelItem.pop()
        return
      }
    },
    editCond(i) {
      console.log(i)
      this.$refs['customScreenRef' + i][0].editCond()
    }
  }
}
</script>

<style lang="scss" scoped>
.entryFunnel {
  height: 150px;
  border-bottom: 1px solid #ececee;
  background: #f4f4f5;
  padding-top: 55px;
  margin-top: -55px;

  .nameFunnel,
  .windowFunnel {
    display: flex;
    align-items: center;
    margin: 20px 0;
  }

  .name,
  .window {
    margin: 10px 15px;
    color: #475669;
    font-size: 14px;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif, 'Apple Color Emoji',
    'Segoe UI Emoji', 'Segoe UI Symbol';
    font-variant: tabular-nums;
    line-height: 1.5;
    font-feature-settings: 'tnum';
    font-weight: 700;
  }

  .item {
    width: 80px;
  }

  .el-icon-info {
    margin-left: -10px;
    cursor: pointer;
  }

  .el-input {
    width: 300px;
    margin-left: 50px;
  }

  .el-select {
    margin-left: -33px;
  }
}

.stepsFunne {
  min-height: 300px;
  padding: 20px 10px 20px 20px;

  .titleTop {
    display: flex;
    justify-content: space-between;

    .title {
      padding-top: 20px;
      margin-bottom: 0.5em;
      color: rgba(0, 0, 0, 0.85);
      font-weight: 500;
      font-size: 18px;
    }

    .titleRight {
      display: flex;
      justify-content: flex-end;

      .el-switch {
        padding-top: 30px;
        margin-right: 20px;
      }

      .el-icon-question {
        font-size: 20px;
        padding-top: 32px;
        cursor: pointer;
      }
    }
  }

  .one,
  .two {
    background: #c3e6d0;
    color: #2dca93;
    width: 36px;
    text-align: center;
    height: 36px;
    line-height: 36px;
    font-size: 16px;
    font-weight: 700;
    margin: 10px;
  }

  .app {
    padding: 6px 10px;
    height: 34px;
    line-height: 20px;
    min-width: 60px;
    font-size: 14px;
    color: #333;
    vertical-align: middle;
    border-radius: 3px;
  }


  .trigger {
    border: none;
    background: white;
    color: #5cb6ff;
    margin: 0 30px;
    font-size: 16px;
    font-weight: 700;
    cursor: pointer;
    width: 140px;
    position: relative;
    display: flex;
    align-items: center;

    .el-icon-plus {
      border: none;
      font-weight: 700;
      font-size: 20px;
      top: 2px;
      position: relative;
    }
  }

  .steps {
    width: 100%;
    position: relative;
    height: auto;

    .step-wrap {
      display: flex;
      align-items: center;
      justify-content: flex-start;

      &:hover {
        background-color: #f9fcfe;

        .click1 {
          box-shadow: 0px 0px 10px;
        }
      }
    }

    .click1 {
      height: 23px;
      line-height: 23px;
      border: 1px solid #dcdfe6;
      width: 200px;
      margin-left: 10px;
      text-indent: 6px;
      color: #bbb;
      position: relative;
      cursor: pointer;

      span {
        width: 200px;
        margin-right: 10px;
        overflow: hidden;
        display: inline-block;
        text-overflow: ellipsis;
        white-space: nowrap;
        word-break: keep-all;
        cursor: pointer;
        color: black;
        span:hover{
          overflow: visible;
        }
      }

      div {
        display: flex;
        align-items: center;
      }
    }

    i {
      position: absolute;
      right: 10px;
      font-size: 14px;
      height: 5px;
    }
  }

  .content {
    display: flex;
    align-items: center;
    border-bottom: 1px solid #dedede;
    background: #f6f8fa;

    p {
      margin-right: 15px;
    }
  }

  .button {
    display: flex;
    justify-content: center;
    position: relative;
    //z-index: 101;
    margin: 60px 0;
    transform: translateY(-20px);
  }
}

.bottom {
  width: 100%;
  height: 60px;
  position: absolute;
  bottom: 0;
  left: 0;
  background: white;
  z-index: 10;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  cursor: pointer;

  .cancel {
    border: none;
  }
}
</style>
